在前一天我們已經完成了「歷史回憶」的雛形:
使用者可以看到自己過去上傳的照片與文字,並以卡片形式排列在畫面上。
而在今天,我們要讓這些回憶「活起來」。透過一個簡單卻具有情感的互動設計——「點擊卡片展開完整日記」,
使用者能像翻開舊相簿一樣,回到當下的瞬間。
前一天的版本中,我們能夠看到所有日記的縮圖、日期與一小段文字預覽,但如果想看完整內容或想回味那張照片的細節,就只能停留在「概覽」層級。
於是今天我加入了兩個關鍵互動設計:
1. 卡片點擊放大預覽:
當使用者點擊任一卡片,畫面會出現一個半透明的遮罩(overlay),中間浮現出完整的日記內容,包括照片、完整文字、日期與時間。
2. 右上角關閉按鈕與外部點擊關閉:
當使用者看完後,可以點擊右上角的 ✖ 或點擊遮罩區域任一處關閉視窗。
這一整段結構就是我們的 「放大日記視窗」。在畫面載入時它是隱藏的(display:none),只有當使用者點擊卡片時才會顯示出來
元素拆解:#overlay
:整個灰黑半透明背景,用於遮罩原畫面#overlay-content
:主要內容框,包含左側圖片與右側文字#overlay-img
:放大後的照片#overlay-text
:右邊的日記文字內容區塊.date
顯示該篇日記的日期(如「2025/10/09」).text
顯示完整日記文字.time
顯示建立時間(如「上午 10:35:22」)#overlay-close
:右上角的「✖」符號,用來關閉預覽
這樣的設計模仿了現代相簿、部落格或 Instagram Lightbox 的呈現方式。讓使用者可以在同一頁中「聚焦」於某一天的內容,而不需要跳轉頁面
<div id="overlay">
<div id="overlay-content">
<img id="overlay-img" src="">
<div id="overlay-text">
<div class="date"></div>
<div class="text"></div>
<div class="time"></div>
</div>
</div>
<div id="overlay-close">✖</div>
</div>
position: fixed
,確保整個畫面被黑色半透明層覆蓋display: none
代表預設不顯示,點擊後才會切換成 display: flex
justify-content
與 align-items
讓內容置中。z-index: 1000
則確保它永遠浮在其他所有元素上方#overlay {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(0,0,0,0.8);
display: none;
justify-content: center;
align-items: center;
z-index: 1000;
}
這裡設定內容框的寬度為螢幕的 90%,並且限制最大寬度 900px,保持在各種裝置上都能良好顯示。
display: flex
讓裡面可以左右並排:
左邊的 img
顯示照片
右邊的 .overlay-text
顯示日期與日記文字
#overlay-content {
background: #fff;
width: 90%;
max-width: 900px;
max-height: 90%;
display: flex;
border-radius: 12px;
overflow: hidden;
}
這段讓圖片與文字區塊左右對分,並透過 object-fit: cover
讓圖片不會被拉伸變形。.overlay-text
內的文字以垂直方向分佈,上方放日期,中間放內容,下方放時間。
#overlay img {
width: 50%;
object-fit: cover;
}
#overlay-text {
width: 50%;
padding: 20px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
position: absolute
讓關閉按鈕固定在右上角,使用者只要一點 ✖,整個預覽就會消失。
#overlay-close {
position: absolute;
top: 10px;
right: 20px;
font-size: 30px;
color: #fff;
cursor: pointer;
}
今天的重點在「事件觸發」與「資料帶入」。以下是新增的互動部分重點解釋
overlay
當使用者點擊某張卡片時,會發生幾件事:
overlayImg.src = entry.image
→ 把該篇日記的圖片放進預覽視窗。overlayText.textContent = entry.text
→ 顯示該篇日記完整文字(不再是30字的摘要)overlayDate.textContent = dateObj.toLocaleDateString()
→ 顯示該日記的日期overlayTime.textContent = dateObj.toLocaleTimeString()
→ 顯示建立時間overlay.style.display = 'flex'
→ 最後一步,讓整個浮動層顯示出來
card.addEventListener('click', () => {
overlayImg.src = entry.image;
overlayText.textContent = entry.text;
overlayDate.textContent = dateObj.toLocaleDateString();
overlayTime.textContent = dateObj.toLocaleTimeString();
overlay.style.display = 'flex';
});
這樣使用者就能「重返昨日」,看到當天完整的記錄。
這裡設計了兩種關閉方式:
overlayClose.addEventListener('click', () => overlay.style.display = 'none');
overlay.addEventListener('click', e => {
if (e.target === overlay) overlay.style.display = 'none';
});
在卡片上,我們同時顯示日期與時間,這樣使用者不但能知道是哪一天,也能回想當時的具體時刻。toLocaleDateString()
會根據使用者語言自動轉成常見格式(例如「2025/10/09」)toLocaleTimeString()
則顯示時間(例如「上午 09:38:21」)
這兩個值在 overlay
模式與卡片縮圖上都會用到,形成一種時間軸感覺,讓整個「回憶系統」更有生命力。
const dateObj = new Date(entry.timestamp);
titleDiv.textContent = dateObj.toLocaleDateString();
timeDiv.textContent = dateObj.toLocaleTimeString();
點擊回憶中的小卡片,就可以看到更詳細的內容啦!